package com.ems.util;

import com.ems.service.impl.CameraServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;

@Slf4j
public class FFMpegUtil {

    /**
     * 利用ffmpeg对摄像头进行推流
     * @param cameraUser：摄像头用户名
     * @param cameraPassword：摄像头密码
     * @param cameraIp：摄像头所在IP
     * @param cameraPort：摄像机端口
     * @param cameraCode：摄像头编码，唯一
     * @return
     */
    public static String cmdFlow (String cameraUser, String cameraPassword, String cameraIp, Integer cameraPort, String cameraCode) {
        StringBuffer stringBuffer = new StringBuffer ();
        stringBuffer.append ( "ffmpeg -re  -rtsp_transport tcp -i " );
        stringBuffer.append ( "\"rtsp://" ).append ( cameraUser ).append ( ":" ).append ( cameraPassword ).append ( "@" ).append ( cameraIp ).append ( ":" ).append ( cameraPort );
        stringBuffer.append ( "/h265/ch01/main/av_stream\"" );
        stringBuffer.append ( " -f flv -vcodec h264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 640*360 -q 10 " + ConstUtil.RTMP );
        stringBuffer.append ( cameraCode ).append ( "\"" );
        return stringBuffer.toString ();
    }

    //获取摄像头http流地址
    public static String getHttpStr (String cameraCode) {
        StringBuffer stringBuffer = new StringBuffer ();
        String localIP = "";
        try {
            localIP = getLinuxLocalIp ();
        } catch ( Exception e ) {
            e.printStackTrace ();
        }
        stringBuffer.append ( "http://" ).append ( localIP ).append ( ConstUtil.FLV_URL ).append ( cameraCode );
        return stringBuffer.toString ();
    }

    /**
     * 执行命令
     * @param cmdFlowStr
     * @param cameraCode
     * @param ip
     */
    public static void getCmdFlowProcess (String cmdFlowStr, String cameraCode, String ip) {
        Thread thread = new Thread () {
            @SneakyThrows
            @Override
            public void run () {
                //ip不在线不推流
                if ( ! HttpUtils.isOnline ( ip ) ) {
                    return;
                }
                log.info ( "推流命令：{}", cmdFlowStr );
                //Process process = Runtime.getRuntime ().exec ( new String[]{"sh", "-c", cmdFlowStr} ); // linux
                Process process = Runtime.getRuntime ().exec ( new String[]{"cmd.exe", "/c", cmdFlowStr} ); // window
                /* 必须加上这两个，不然推流会停止 */
                new Thread ( new DealProcessStream ( process.getInputStream () ) ).start ();
                new Thread ( new DealProcessStream ( process.getErrorStream () ) ).start ();
                CameraServiceImpl.processMap.put ( cameraCode, process );
                process.waitFor ();
            }
        };
        thread.start ();
    }

    //停止推流进程
    public static void getStopProcess (Process process) {
        process.destroy ();
    }

    //获取抓图cmd命令
    public static String getPictureStr (String userName, String password, String ip, String port, String xj, String ch, String picPath) throws UnknownHostException {
        StringBuffer stringBuffer = new StringBuffer ();
        stringBuffer.append ( "ffmpeg -i " );
        stringBuffer.append ( "rtsp://" ).append ( userName ).append ( ":" ).append ( password ).append ( "@" ).append ( ip ).append ( ":" ).append ( port );
        stringBuffer.append ( "/h265/ch01/main/av_stream" );
        stringBuffer.append ( " -y -f image2 -t 0.001 -s 352x240 " );
        stringBuffer.append ( picPath );
        return stringBuffer.toString ();
    }

    //执行截图cmd命令
    public static void getCmdPicture (String cmdStr) throws IOException {
        Thread thread = new Thread () {
            @SneakyThrows
            @Override
            public void run () {
                Runtime.getRuntime ().exec ( cmdStr );
            }
        };
        thread.start ();
    }

    public static String getRtspStr (String userName, String password, String ip, String port) throws UnknownHostException {
        StringBuffer stringBuffer = new StringBuffer ();
        stringBuffer.append ( "rtsp://" ).append ( userName ).append ( ":" ).append ( password ).append ( "@" ).append ( ip ).append ( ":" ).append ( port );
        stringBuffer.append ( "/h265/ch01/main/av_stream" );
        return stringBuffer.toString ();
    }

    public static String getHwRtspStr (String userName, String password, String ip, String port, String ch) throws UnknownHostException {
        StringBuffer stringBuffer = new StringBuffer ();
        //rtsp://admin:Abc.12345@192.168.1.64:554/ch1/stream0
        stringBuffer.append ( "rtsp://" ).append ( userName ).append ( ":" ).append ( password ).append ( "@" ).append ( ip ).append ( ":" ).append ( port );
        stringBuffer.append ( "/ch" + ch + "/stream0" );
        return stringBuffer.toString ();
    }

    /**
     * 获取Linux下的IP地址
     * @return IP地址
     * @throws Exception
     */
    private static String getLinuxLocalIp () {
        String ip = "";
        try {
            for ( Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces (); en.hasMoreElements (); ) {
                NetworkInterface intf = en.nextElement ();
                String name = intf.getName ();
                if ( ! name.contains ( "docker" ) && ! name.contains ( "lo" ) ) {
                    for ( Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses (); enumIpAddr.hasMoreElements (); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement ();
                        if ( ! inetAddress.isLoopbackAddress () ) {
                            String ipaddress = inetAddress.getHostAddress ().toString ();
                            if ( ! ipaddress.contains ( "::" ) && ! ipaddress.contains ( "0:0:" ) && ! ipaddress.contains ( "fe80" ) ) {
                                ip = ipaddress;
                                System.out.println ( ipaddress );
                            }
                        }
                    }
                }
            }
        } catch ( Exception ex ) {
            ex.printStackTrace ();
        }
        return ip;
    }
}
